﻿using System;
using System.ServiceModel.Syndication;
using NCMIS.ObjectModel.Rest;
using NCMIS.ObjectModel;
using NCMIS.ServiceModel.Syndication;
using System.IO;

namespace NCMIS.Client
{
    public class CmisDocument
    {
        /// <summary>
        /// Creates a cmis:document instance at the targeted CMIS service.
        /// </summary>
        /// <param name="webRequest">The web request to use.</param>
        /// <param name="name">The name of the document to create.</param>
        /// <param name="childrenFeedUri">The children feed, where to create the document.</param>
        /// <returns>A <see cref="System.ServiceModel.Syndication.SyndicationItem"/> object holding the document instance.</returns>
        public static SyndicationItem CreateDocument(CmisWebRequest webRequest, string name, Uri childrenFeedUri, byte[] fileContent)
        {
            SyndicationItem docEntry = CreateDocEntry(name, fileContent);
            //ContentStream contentStream = CreateContentStream(fileContent);     // not called yet
            docEntry = webRequest.InvokeSyndicationFeed(childrenFeedUri.AbsoluteUri, docEntry);

            return docEntry;
        }

        /// <summary>
        /// Creates a cmis:document instance at the targeted CMIS service.
        /// </summary>
        /// <param name="webRequest">The web request to use.</param>
        /// <param name="name">The name of the document to create.</param>
        /// <param name="childrenFeedUri">The children feed, where to create the document.</param>
        /// <param name="contentStream">The content stream for the new document.</param>
        /// <returns>A <see cref="System.ServiceModel.Syndication.SyndicationItem"/> object holding the document instance.</returns>
        public static SyndicationItem CreateDocument(CmisWebRequest webRequest, string name, Uri childrenFeedUri, Stream contentStream)
        {
            SyndicationItem docEntry = CreateDocEntry(name, contentStream);

            docEntry = webRequest.InvokeSyndicationFeed(childrenFeedUri.AbsoluteUri, docEntry);

            return docEntry;
        }

         /// <summary>
        /// Creates a folder entry.
        /// </summary>
        /// <param name="name">The name of the folder to create.</param>
        /// <returns>A <see cref="System.ServiceModel.Syndication.SyndicationItem"/> object holding the folder instance.</returns>
        private static SyndicationItem CreateDocEntry(string name, byte[] data)
        {
            CmisObject cmisObject = CreateCmisObject(name, data.Length);
            Content content = CmisSyndicationItem.CreateCmisraContent(data, name);

            CmisSyndicationItem entry = new CmisSyndicationItem()
            {
                Id = String.Format("urn:uuid:{0}-object", name),
                Title = new TextSyndicationContent(name),
                LastUpdatedTime = new DateTimeOffset(DateTime.Now),
                PublishDate = new DateTimeOffset(DateTime.Now)
            };

            entry.Authors.Add(new SyndicationPerson() { Name = "Administrator" });
            entry.AddContent(content);
            entry.AddObject(cmisObject);

            return entry;
        }

        /// <summary>
        /// Creates a folder entry.
        /// </summary>
        /// <param name="name">The name of the folder to create.</param>
        /// <returns>A <see cref="System.ServiceModel.Syndication.SyndicationItem"/> object holding the folder instance.</returns>
        protected static SyndicationItem CreateDocEntry(string name, Stream contentStream)
        {
            CmisObject cmisObject = CreateCmisObject(name, (int)contentStream.Length);

            CmisRaContentStream content = CmisSyndicationItem.CreateCmisraContentStream(name, contentStream);

            CmisSyndicationItem entry = new CmisSyndicationItem()
            {
                Id = String.Format("urn:uuid:{0}-object", name),
                Title = new TextSyndicationContent(name),
                LastUpdatedTime = new DateTimeOffset(DateTime.Now),
                PublishDate = new DateTimeOffset(DateTime.Now)
            };

            entry.Authors.Add(new SyndicationPerson() { Name = "Administrator" });

            // add content specifying our own serializer that reads from the 
            // stream to serialize rather than from in memory
            entry.AddContent(content, new CmisRaContentStreamSerializer());
            entry.AddObject(cmisObject);

            return entry;
        }

        /// <summary>
        /// Creates a CMIS document object with a set of properties.
        /// </summary>
        /// <param name="name">the name of the document to create.</param>
        /// <param name="name">content length of the document to create.</param>
        /// <returns>A <see cref="NCMIS.ObjectModel.CmisObject"/> object holding the document instance.</returns>
        private static CmisObject CreateCmisObject(string name, int contentLength)
        {
            CmisObject cmisObject = new CmisObject();

            CmisProperties properties = new CmisProperties()
            {
                Items = new CmisProperty[]
                {
                    //PropertyFactory.CreateObjectId(name),     // Commented since objectId isn't needed
                    PropertyFactory.CreateBaseTypeId("cmis:document"),
                    PropertyFactory.CreateCreatedBy("Administrator"),
                    PropertyFactory.CreateCreationDate(DateTime.Now),
                    PropertyFactory.CreateContentStreamFileName(name),
                    PropertyFactory.CreateContentStreamId(name + "ContentStream"),
                    PropertyFactory.CreateContentStreamLength(contentLength),
                    PropertyFactory.CreateContentStreamMimeType("text/plain"),
                    PropertyFactory.CreateIsImmutable(false),
                    PropertyFactory.CreateIsLatestMajorVersion(true),
                    PropertyFactory.CreateIsVersionSeriesCheckedOut(false),
                    PropertyFactory.CreateLastModifiedBy("Administrator"),
                    PropertyFactory.CreateLastModificationDate(DateTime.Now),
                    PropertyFactory.CreateName(name),
                    PropertyFactory.CreateObjectTypeId("cmis:document"),
                    PropertyFactory.CreateParentId("rootfolder"),
                    PropertyFactory.CreatePath("/")
                }
            };
            cmisObject.Properties = properties;

            return cmisObject;
        }
    }
}
